package methods

import (
	"freely/src/constant"
	"time"

	"github.com/dgrijalva/jwt-go"
)

// JWT 格式
type JwtSchema struct {
	UserID             uint   `json:"userId"`
	Username           string `json:"username"`
	RoleID             uint   `json:"roleId"`
	Role               string `json:"role"`
	LoginAt            string `json:"loginAt"` // 登录设备：浏览器、小程序、APP 之类的
	jwt.StandardClaims        // jwt 标准配置
}

// 需要配置的参数
type JwtData struct {
	UserID   uint
	Username string
	RoleID   uint
	Role     string
	LoginAt  string
}

var jwtCode = []byte("rex-service-go-1689266196285-4e7426cb23fd43ac")

/**
 * 创建token
 * @param data 包含的内容
 * @param exp 有效时长
 * @return string token内容
 * @return time.Time 做续签时需要用到的刷新时间
 * @return time.Time 过期时间
 * @return error 错误信息，如果顺利执行则为nil
 */
func TokenCreate(data *JwtData, exp time.Duration) (string, time.Time, time.Time, error) {
	now := time.Now()
	refTime := now.Add(exp / 2)
	expires := now.Add(exp)

	claims := JwtSchema{
		UserID:   data.UserID,
		Username: data.Username,
		RoleID:   data.RoleID,
		Role:     data.Role,
		LoginAt:  data.LoginAt,
		StandardClaims: jwt.StandardClaims{
			Issuer:    "Rex",
			ExpiresAt: expires.Unix(), // 过期时间
			NotBefore: now.Unix(),     // 生效时间
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	str, err := token.SignedString(jwtCode)

	return str, refTime, expires, err
}

/**
 * 解析token
 */
func TokenParse(tokenStr string) (*JwtSchema, error) {
	token, err := jwt.ParseWithClaims(tokenStr, &JwtSchema{}, func(t *jwt.Token) (interface{}, error) {
		return jwtCode, nil
	})

	if err != nil {
		return nil, constant.ErrTokenExpired
	}

	return token.Claims.(*JwtSchema), nil
}
